home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / a_utils / perl / msds-prl / perl386.zoo / msdos.c < prev    next >
C/C++ Source or Header  |  1992-12-17  |  6KB  |  301 lines

  1. static char *rcsid = "$Id: msdos.c 1.4 92/08/29 20:24:06 doi Exp $";
  2. /* RCSfile: msdos.c,v Revision: 4.0.1.1 Date: 91/06/07 11:22:37 
  3.  *
  4.  *    (C) Copyright 1989, 1990 Diomidis Spinellis.
  5.  *
  6.  *    You may distribute under the terms of either the GNU General Public
  7.  *    License or the Artistic License, as specified in the README file.
  8.  *
  9.  * Log:    msdos.c,v 
  10.  * Revision 4.0.1.1  91/06/07  11:22:37  lwall
  11.  * patch4: new copyright notice
  12.  * 
  13.  * Revision 4.0  91/03/20  01:34:46  lwall
  14.  * 4.0 baseline.
  15.  * 
  16.  * Revision 3.0.1.1  90/03/27  16:10:41  lwall
  17.  * patch16: MSDOS support
  18.  * 
  19.  * Revision 1.1  90/03/18  20:32:01  dds
  20.  * Initial revision
  21.  *
  22.  */
  23.  
  24. /*
  25.  * Various Unix compatibility functions for MS-DOS.
  26.  */
  27.  
  28. #include "../EXTERN.h"
  29. #include "../perl.h"
  30.  
  31. #include <dos.h>
  32. #ifndef DJGPP
  33. #include <process.h>
  34. #endif /* !DJGPP */
  35.  
  36. /*
  37.  * Interface to the MS-DOS ioctl system call.
  38.  * The function is encoded as follows:
  39.  * The lowest nibble of the function code goes to AL
  40.  * The two middle nibbles go to CL
  41.  * The high nibble goes to CH
  42.  *
  43.  * The return code is -1 in the case of an error and if successful
  44.  * for functions AL = 00, 09, 0a the value of the register DX
  45.  * for functions AL = 02 - 08, 0e the value of the register AX
  46.  * for functions AL = 01, 0b - 0f the number 0
  47.  *
  48.  * Notice that this restricts the ioctl subcodes stored in AL to 00-0f
  49.  * In the Ralf Borwn interrupt list 90.1 there are no subcodes above AL=0f
  50.  * so we are ok.
  51.  * Furthermore CH is also restriced in the same area.  Where CH is used as a
  52.  * code it always is between 00-0f.  In the case where it forms a count
  53.  * together with CL we arbitrarily set the highest count limit to 4095.  It
  54.  * sounds reasonable for an ioctl.
  55.  * The other alternative would have been to use the pointer argument to
  56.  * point the the values of CX.  The problem with this approach is that
  57.  * of accessing wild regions when DX is used as a number and not as a
  58.  * pointer.
  59.  */
  60. int
  61. ioctl(int handle, int function, char *data)
  62. {
  63.     union REGS      srv;
  64.     struct SREGS    segregs;
  65.  
  66.     srv.h.ah = 0x44;
  67.     srv.h.al = (unsigned char)(function & 0x0F);
  68.     srv.x.bx = handle;
  69.     srv.x.cx = function >> 4;
  70. #ifndef DJGPP
  71.     /* DJGPP doesn't use segments */
  72.     segread(&segregs);
  73. #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  74.     segregs.ds = FP_SEG(data);
  75.     srv.x.dx = FP_OFF(data);
  76. #else
  77.     srv.x.dx = (unsigned int) data;
  78. #endif
  79. #endif /* !DJGPP */
  80.     intdosx(&srv, &srv, &segregs);
  81.     if (srv.x.cflag & 1) {
  82.         switch(srv.x.ax ){
  83.         case 1:
  84.             errno = EINVAL;
  85.             break;
  86.         case 2:
  87.         case 3:
  88.             errno = ENOENT;
  89.             break;
  90.         case 4:
  91.             errno = EMFILE;
  92.             break;
  93.         case 5:
  94. #ifdef DJGPP
  95.             errno = EACCES;
  96. #else
  97.             errno = EPERM;
  98. #endif /* DJGPP */
  99.             break;
  100.         case 6:
  101.             errno = EBADF;
  102.             break;
  103.         case 8:
  104.             errno = ENOMEM;
  105.             break;
  106.         case 0xc:
  107.         case 0xd:
  108.         case 0xf:
  109.             errno = EINVAL;
  110.             break;
  111.         case 0x11:
  112.             errno = EXDEV;
  113.             break;
  114.         case 0x12:
  115. #ifdef DJGPP
  116.             errno = ENOENT;
  117. #else
  118.             errno = ENFILE;
  119. #endif /* DJGPP */
  120.             break;
  121.         default:
  122. #ifdef DJGPP
  123.             errno = ERANGE;
  124. #else
  125.             errno = EZERO;
  126. #endif /* DJGPP */
  127.             break;
  128.         }
  129.         return -1;
  130.     } else {
  131.         switch (function & 0xf) {
  132.         case 0: case 9: case 0xa:
  133.             return srv.x.dx;
  134.         case 2: case 3: case 4: case 5:
  135.         case 6: case 7: case 8: case 0xe:
  136.             return srv.x.ax;
  137.         case 1: case 0xb: case 0xc: case 0xd:
  138.         case 0xf:
  139.         default:
  140.             return 0;
  141.         }
  142.     }
  143. }
  144.  
  145.  
  146. /*
  147.  * Sleep function.
  148.  */
  149. unsigned int
  150. sleep(unsigned len)
  151. {
  152.     time_t end;
  153.  
  154.     end = time((time_t *)0) + len;
  155.     while (time((time_t *)0) < end)
  156.         ;
  157. }
  158.  
  159. /*
  160.  * Just pretend that everyone is a superuser
  161.  */
  162. #define ROOT_UID    0
  163. #define ROOT_GID    0
  164.  
  165. #ifndef DJGPP
  166. unsigned int
  167. getuid(void)
  168. {
  169.     return ROOT_UID;
  170. }
  171.  
  172. unsigned int
  173. geteuid(void)
  174. {
  175.     return ROOT_UID;
  176. }
  177.  
  178. int
  179. getgid(void)
  180. {
  181.     return ROOT_GID;
  182. }
  183.  
  184. int
  185. getegid(void)
  186. {
  187.     return ROOT_GID;
  188. }
  189. #endif /* !DJGPP */
  190.  
  191. int
  192. setuid(int uid)
  193. { return (uid==ROOT_UID?0:-1); }
  194.  
  195. int
  196. setgid(int gid)
  197. { return (gid==ROOT_GID?0:-1); }
  198.  
  199. /*
  200.  * The following code is based on the do_exec and do_aexec functions
  201.  * in file doio.c
  202.  */
  203. int
  204. do_aspawn(really,arglast)
  205. STR *really;
  206. int *arglast;
  207. {
  208.     register STR **st = stack->ary_array;
  209.     register int sp = arglast[1];
  210.     register int items = arglast[2] - sp;
  211.     register char **a;
  212.     char **argv;
  213.     char *tmps;
  214.     int status;
  215.  
  216.     if (items) {
  217.     New(1101,argv, items+1, char*);
  218.     a = argv;
  219.     for (st += ++sp; items > 0; items--,st++) {
  220.         if (*st)
  221.         *a++ = str_get(*st);
  222.         else
  223.         *a++ = "";
  224.     }
  225.     *a = Nullch;
  226. #ifdef DJGPP
  227.     {
  228.     char sys_string[256];
  229.     register int i;
  230.  
  231.     if (really && *(tmps = str_get(really)))
  232.         strcpy(sys_string, tmps);
  233.     else
  234.         strcpy(sys_string, argv[0]);
  235.     for (i = 1; argv[i]; i++) {
  236.         strcat(sys_string, " ");
  237.         strcat(sys_string, argv[i]);
  238.     }
  239.     status = system(sys_string);
  240.     }
  241. #else
  242.     if (really && *(tmps = str_get(really)))
  243.         status = spawnvp(P_WAIT,tmps,argv);
  244.     else
  245.         status = spawnvp(P_WAIT,argv[0],argv);
  246. #endif /* DJGPP */
  247.     Safefree(argv);
  248.     }
  249.     return status;
  250. }
  251.  
  252.  
  253. int
  254. do_spawn(cmd)
  255. char *cmd;
  256. {
  257.     register char **a;
  258.     register char *s;
  259.     char **argv;
  260.     char flags[10];
  261.     int status;
  262.     char *shell, *cmd2;
  263.  
  264. #ifdef DJGPP
  265.         return system(cmd);
  266. #else
  267.     /* save an extra exec if possible */
  268.     if ((shell = getenv("COMSPEC")) == 0)
  269.     shell = "\\command.com";
  270.  
  271.     /* see if there are shell metacharacters in it */
  272.     if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|'))
  273.       doshell:
  274.         return spawnl(P_WAIT,shell,shell,"/c",cmd,(char*)0);
  275.  
  276.     New(1102,argv, strlen(cmd) / 2 + 2, char*);
  277.  
  278.     New(1103,cmd2, strlen(cmd) + 1, char);
  279.     strcpy(cmd2, cmd);
  280.     a = argv;
  281.     for (s = cmd2; *s;) {
  282.     while (*s && isspace(*s)) s++;
  283.     if (*s)
  284.         *(a++) = s;
  285.     while (*s && !isspace(*s)) s++;
  286.     if (*s)
  287.         *s++ = '\0';
  288.     }
  289.     *a = Nullch;
  290.     if (argv[0])
  291.     if ((status = spawnvp(P_WAIT,argv[0],argv)) == -1) {
  292.         Safefree(argv);
  293.         Safefree(cmd2);
  294.         goto doshell;
  295.     }
  296.     Safefree(cmd2);
  297.     Safefree(argv);
  298.     return status;
  299. #endif /* DJGPP */
  300. }
  301.